/*****************************************************
*
*               COPYRIGHT (c) 2015-2017 Hargic Corporation
*                         All Rights Reserved
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Hargic
* Corporation or its licensors.  Title to the Material remains
* with Hargic Corporation or its suppliers and licensors.
*
* The Material is protected by worldwide copyright and trade secret
* laws and treaty provisions. No part of the Material may be used,
* copied, reproduced, modified, published, uploaded, posted, transmitted,
* distributed, or disclosed in any way except in accordance with the
* applicable license agreement.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you by
* disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel, except in accordance with the
* applicable license agreement.
*
* Unless otherwise agreed by Hargic in writing, you may not remove or
* alter this notice or any other notice embedded in Materials by Hargic
* or Hargic's suppliers or licensors in any way.
*
** Author: shengda.huang
** Date: 2018-05-26
*
*****************************************************/

/***** Include files ********************************/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <bcm2835.h>
#include "am23xx_1wire.h"

/***** Defines **************************************/

#define SDA_PIN         5
#define TEST_PIN        12

/***** Define structure *****************************/

/***** Define constant ******************************/

/***** Define global ********************************/

/***** Define Prototype of functions ****************/

static int am23xx_gpio_init(void)
{
    if (!bcm2835_init())
    {
        printf("bcm2835_init failed. Are you running as root??\n");
        return -1;
    }

    bcm2835_gpio_fsel(SDA_PIN, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(TEST_PIN, BCM2835_GPIO_FSEL_OUTP);

    bcm2835_gpio_set(SDA_PIN);
    return 0;
}

static void am3201_gpio_pullup(void)
{
    bcm2835_gpio_set_pud(SDA_PIN, BCM2835_GPIO_PUD_UP);
}

static void am23xx_gpio_set_dir(int dir)
{
    if (dir == AM23XX_GPIO_DIR_INPUT)
        bcm2835_gpio_fsel(SDA_PIN, BCM2835_GPIO_FSEL_INPT);
    else
        bcm2835_gpio_fsel(SDA_PIN, BCM2835_GPIO_FSEL_OUTP);
}

static void am23xx_gpio_set_output(int level)
{
    if (level == AM23XX_GPIO_LEVEL_LOW)
        bcm2835_gpio_clr(SDA_PIN);
    else
        bcm2835_gpio_set(SDA_PIN);
}

static int am23xx_gpio_get_level(void)
{
    if (bcm2835_gpio_lev(SDA_PIN) == LOW)
        return AM23XX_GPIO_LEVEL_LOW;
    else
        return AM23XX_GPIO_LEVEL_HIGH;
}

static void am23xx_delay_us(int us)
{
    bcm2835_delayMicroseconds(us);
}

static void am23xx_test_pin_set(int level)
{
    if (level == AM23XX_GPIO_LEVEL_LOW)
        bcm2835_gpio_clr(TEST_PIN);
    else
        bcm2835_gpio_set(TEST_PIN);
}

static int am23xx_sample(void)
{
    unsigned short humidity, temperature;
    unsigned char data[5], csum;
    char symbol;
    int ret;

    ret = am23xx_start();
    if (ret != 0)
    {
        printf("%s: am23xx_start failed %d\n", __func__, ret);
        return -1;
    }

    ret = am23xx_read_nbyte(data, 5);
    printf("%s: read data[0] %02x data[1] %02x data[2] %02x data[3] %02x data[4] %02x\n", __func__,
                                                        data[0], data[1], data[2], data[3], data[4]);
    if (ret != 0)
    {
        printf("%s: am23xx_read_nbyte failed %d\n", __func__, ret);
        return -2;
    }

    ret = am23xx_release();
    if (ret != 0)
    {
        printf("%s: am23xx_release failed %d\n", __func__, ret);
        return -4;
    }

    csum = data[0] + data[1] + data[2] + data[3];
    if (data[4] != csum)
    {
        printf("%s: checksum error\n", __func__);
        return -3;
    }

    humidity = data[0] << 8;
    humidity += data[1];
    temperature = data[2] << 8;
    temperature += data[3];
    symbol = temperature & 0x8000 ? '-': '\0';
    printf("%s: get humidity %d temperature %c%d\n", __func__, humidity, symbol, temperature & 0x7fff);

    return 0;
}

/**
 * @brief
 * @param  None
 * @retval None
 */
int main(int argc, char **argv)
{
    am23xx_func_t func;
    int cnt, success;

    if (am23xx_gpio_init() != 0)
    {
        printf("gpio init failed\n");
        return -1;
    }

    printf("%s: wait %ds to stable sensor\n", __func__, 4);
    sleep(4);

    memset(&func, 0x0, sizeof(am23xx_func_t));
    func.gpio_pullup        = am3201_gpio_pullup;
    func.gpio_set_dir       = am23xx_gpio_set_dir;
    func.gpio_set_output    = am23xx_gpio_set_output;
    func.gpio_get_level     = am23xx_gpio_get_level;
    func.delay_us           = am23xx_delay_us;
    func.test_pin_set       = am23xx_test_pin_set;
    am23xx_register_gpio_func(&func);

    cnt = success = 0;
    while (cnt < 500)
    {
        if (am23xx_sample() == 0)
            success++;
        // else
        //  break;

        printf("%s: cnt %d success %d\n", __func__, ++cnt, success);

        sleep(4);
    }

    return 0;
}

/* End of file */



